import THREE from './three.js';
import Stats from '../three/stats.module.js';
import { OrbitControls } from '../three/OrbitControls.js';

function Level(){
    var self = {};
    self.default_scene = function(){

        self.scene.background = new THREE.Color( 0xcce0ff );
        self.scene.fog = new THREE.Fog( 0xcce0ff, 500*10, 10000 );

        self.camera.position.set( 0, 50*10*5, 1500 );

        // lights

        self.scene.add( new THREE.AmbientLight( 0x666666 ) );

        var light = new THREE.DirectionalLight( 0xdfebff, 1 );

        light.position.set( 0, 50*10*5, 1500 );

        light.castShadow = true;

        light.shadow.mapSize.width = 1024*4;
        light.shadow.mapSize.height = 1024*4;

        var d = 300*10;

        light.shadow.camera.left = - d;
        light.shadow.camera.right = d;
        light.shadow.camera.top = d;
        light.shadow.camera.bottom = - d;

        light.shadow.camera.far = 1000*5;

        self.scene.add( light );
        
        var loader = new THREE.TextureLoader();
        self.need_load();
        var groundTexture = loader.load( './img/ground.png' , self.loaded);
        groundTexture.wrapS = groundTexture.wrapT = THREE.RepeatWrapping;
        groundTexture.repeat.set( 50, 50 );
        groundTexture.anisotropy = 16;
        groundTexture.encoding = THREE.sRGBEncoding;
        var groundMaterial = new THREE.MeshLambertMaterial( { map: groundTexture } );
        var mesh = new THREE.Mesh( new THREE.PlaneBufferGeometry( 20000, 20000 ), groundMaterial );
        mesh.position.y = - 250/5;
        mesh.rotation.x = - Math.PI / 2;
        mesh.rotation.z = Math.PI / 4;
        mesh.receiveShadow = true;
        self.scene.add( mesh );

        return {light, mesh};
    };
    self.create = function(){
        self.container = document.createElement( 'div' );
        self.scene = new THREE.Scene();
        self.camera = new THREE.PerspectiveCamera( 30, window.innerWidth / window.innerHeight, 1, 10000 );

        for (let i = 0; i < self.on_create.length; i++) {
            self.on_create[i]();
        }

    };
    self.onWindowResize = function () {

        self.camera.aspect = window.innerWidth / window.innerHeight;
        self.camera.updateProjectionMatrix();
    
        self.renderer.setSize( window.innerWidth, window.innerHeight );
    
    };
    self.animate = function ( now ) {

        window.requestAnimationFrame( self.animate );
        for (let i = 0; i < self.on_animate.length; i++) {
            self.on_animate[i](now);
        }
        self.renderer.render( self.scene, self.camera );
        self.stats.update();

    };
    self.on_create = [];
    self.on_animate = [];
    self.on_start = [];
    self.default_controls = function(){
        var controls = new OrbitControls( self.camera, self.renderer.domElement );
        controls.maxPolarAngle = Math.PI * 0.5;
        controls.minDistance = 1000;
        controls.maxDistance = 5000;
        return controls;
    }
    self.start = function(){
        self.load_num__ -= 1;
        if(self.load_num__!==0){
            return;
        }
        document.body.appendChild( self.container );

        self.renderer = new THREE.WebGLRenderer( { antialias: true } );
        self.renderer.setPixelRatio( window.devicePixelRatio );
        self.renderer.setSize( window.innerWidth, window.innerHeight );

        self.container.appendChild( self.renderer.domElement );

        self.renderer.outputEncoding = THREE.sRGBEncoding;

        self.renderer.shadowMap.enabled = true;

        // self.controls
        if(!self.controls){
            self.controls = self.default_controls();
        }

        // performance monitor

        self.stats = new Stats();
        self.container.appendChild( self.stats.dom );

        window.addEventListener( 'resize', self.onWindowResize, false );
        for (let i = 0; i < self.on_start.length; i++) {
            self.on_start[i]();
        }
        self.animate(0);
    };
    self.load_num__ = 1;
    self.need_load = function(){
        self.load_num__ += 1;
    }
    self.loaded = self.start;
    self.launch = function(){
        setTimeout(self.create, 0);
        const startButton = document.getElementById( 'startButton' );
        startButton.addEventListener( 'click', function () {
            const overlay = document.getElementById( 'overlay' );
            overlay.remove();
            self.start();
        }, false );
    };
    self.removeEventListener = [];
    self.addEventListener = function(event, func, arg = false){
        window.addEventListener( event, func, arg );
        self.removeEventListener.push(function(){
            window.removeEventListener( event, func );
        });
    };
    self.dispose = function(){
        document.body.removeChild( self.container );
        window.removeEventListener( 'resize', self.onWindowResize );
        self.removeEventListener.forEach(function(f){f();});
        if(self.controls.dispose){
            self.controls.dispose();
        }
        self = null;
    };
    return self;
}

export default Level;